﻿
// CubicBezierCurveView.cpp: CCubicBezierCurveView 类的实现
//

#include "pch.h"
#include "framework.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "CubicBezierCurve.h"
#endif

#include "CubicBezierCurveDoc.h"
#include "CubicBezierCurveView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CCubicBezierCurveView

IMPLEMENT_DYNCREATE(CCubicBezierCurveView, CView)

BEGIN_MESSAGE_MAP(CCubicBezierCurveView, CView)
	// 标准打印命令
	ON_COMMAND(ID_FILE_PRINT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, &CView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, &CView::OnFilePrintPreview)
	ON_COMMAND(ID_32771, &CCubicBezierCurveView::OnStaticImage)
	ON_COMMAND(ID_32772, &CCubicBezierCurveView::OnDynamicImage)
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()

// CCubicBezierCurveView 构造/析构

CCubicBezierCurveView::CCubicBezierCurveView() noexcept
{
	InitCirclePoints();
	
	bezierC.SetStep(10);
	circle.SetStep(10);

	count = 0;
	isStaticShow = true;
	needEmpty = true;
}

CCubicBezierCurveView::~CCubicBezierCurveView()
{
}

BOOL CCubicBezierCurveView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CView::PreCreateWindow(cs);
}

// CCubicBezierCurveView 绘图

void CCubicBezierCurveView::DrawCoordinate(CDC* pDC, CRect& rect)
{
	CPen pen(PS_SOLID, 3, RGB(0, 0, 0));
	pDC->SelectObject(&pen);

	pDC->MoveTo(rect.left, 0);
	pDC->LineTo(rect.right, 0);

	pDC->MoveTo(0, rect.top);
	pDC->LineTo(0, rect.bottom);
}

void CCubicBezierCurveView::InitCurves()
{
	p[0].x = 0;
	p[0].y = 200;

	p[1].x = 110;
	p[1].y = 200;

	p[2].x = 200;
	p[2].y = 110;

	p[3].x = 200;
	p[3].y = 0;


	bezierC.SetStep(20);
	bezierC.SetPoints(p);
}

void CCubicBezierCurveView::InitCirclePoints()
{
	double m = 0.5523;

	cp[0].x = 1;
	cp[0].y = 0;

	cp[1].x = 1;
	cp[1].y = m;

	cp[2].x = m;
	cp[2].y = 1;

	cp[3].x = 0;
	cp[3].y = 1;

	cp[4].x = -m;
	cp[4].y = 1;

	cp[5].x = -1;
	cp[5].y = m;

	cp[6].x = -1;
	cp[6].y = 0;

	cp[7].x = -1;
	cp[7].y = -m;

	cp[8].x = -m;
	cp[8].y = -1;

	cp[9].x = 0;
	cp[9].y = -1;

	cp[10].x = m;
	cp[10].y = -1;

	cp[11].x = 1;
	cp[11].y = -m;

	Transformation trans;

	for (int i = 0; i < 12; ++i)
	{
		trans.Scale(200, 200, cp[i]);
	}

	circle.SetPoints(cp);
}

void CCubicBezierCurveView::OnDraw(CDC* pDC)
{
	CCubicBezierCurveDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	CRect rect;
	GetClientRect(&rect);
	int width = rect.Width();
	int height = rect.Height();

	pDC->SetMapMode(MM_ANISOTROPIC);					// 各向异性，图案会随窗口的长宽比例而调整自己的长宽
	pDC->SetWindowExt(width, height);					// 设置窗口范围
	pDC->SetViewportExt(width, -height);				// 设置视图大小，得到一个x轴水平向右，y轴垂直向上，原点位于视图左下角的新视图
	pDC->SetViewportOrg(width / 2, height / 2);			// 设置原点
	
	rect.OffsetRect(-width / 2, -height / 2);

	if (!needEmpty)
	{
		if (isStaticShow)
		{
			DrawCoordinate(pDC, rect);
			circle.DrawCircle(pDC);
		}
		else
			bezierC.CalCulateCurve(pDC, rect);
	}
}


// CCubicBezierCurveView 打印

BOOL CCubicBezierCurveView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// 默认准备
	return DoPreparePrinting(pInfo);
}

void CCubicBezierCurveView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加额外的打印前进行的初始化过程
}

void CCubicBezierCurveView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: 添加打印后进行的清理过程
}


// CCubicBezierCurveView 诊断

#ifdef _DEBUG
void CCubicBezierCurveView::AssertValid() const
{
	CView::AssertValid();
}

void CCubicBezierCurveView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCubicBezierCurveDoc* CCubicBezierCurveView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCubicBezierCurveDoc)));
	return (CCubicBezierCurveDoc*)m_pDocument;
}
#endif //_DEBUG


// CCubicBezierCurveView 消息处理程序


void CCubicBezierCurveView::OnStaticImage()
{
	isStaticShow = true;
	needEmpty = false;

	Invalidate(TRUE);
}


void CCubicBezierCurveView::OnDynamicImage()
{
	count = 0;
	isStaticShow = false;
	needEmpty = true;

	Invalidate(TRUE);
}

void CCubicBezierCurveView::OnLButtonDown(UINT nFlags, CPoint point)
{
	if (isStaticShow)
		return;

	CDC* pDC = GetDC();

	CRect rect;
	GetClientRect(&rect);
	int width = rect.Width();
	int height = rect.Height();

	pDC->SetMapMode(MM_ANISOTROPIC);					// 各向异性，图案会随窗口的长宽比例而调整自己的长宽
	pDC->SetWindowExt(width, height);					// 设置窗口范围
	pDC->SetViewportExt(width, -height);				// 设置视图大小，得到一个x轴水平向右，y轴垂直向上，原点位于视图左下角的新视图
	pDC->SetViewportOrg(width / 2, height / 2);			// 设置原点

	pDC->DPtoLP(&point);

	CPen pen(PS_SOLID, 3, RGB(0, 0, 0));
	pDC->SelectObject(&pDC);

	if (count < 4)
	{
		p[count] = CPoint2D(point);
		pDC->Ellipse(p[count].x - 3, p[count].y - 3, p[count].x + 3, p[count].y + 3);
	}

	pDC->DeleteDC();

	count++;

	if (count == 4)
	{
		bezierC.SetPoints(p);

		needEmpty = false;
		Invalidate(TRUE);
	}
	
	CView::OnLButtonDown(nFlags, point);
}
